feat: unify widget hiding into a single hideable-state system - #430
feat: unify widget hiding into a single hideable-state system#430zachthedev wants to merge 1 commit into
Conversation
|
@zachthedev Can you go ahead and rebase this on main and resolve any issues? |
Will do sometime in the next 24 hours |
4d51f8c to
9b4424d
Compare
|
Rebased onto |
9b4424d to
592db94
Compare
Ready for review. Thanks much! |
592db94 to
36a0a27
Compare
0db28b9 to
fd0f726
Compare
|
Rebased onto current Four migration bugs, all fixed:
One new state: Git CI Status declares The old test sampled one widget per rule constant with no tie to the registry, which is how lint clean, |
Implements the unified hideable-state system proposed in sirmalloc#428. - Add src/widgets/shared/hideable.ts: widgets declare hideable conditions via getHideableStates(); a single metadata.hide key stores enabled state keys as a comma-separated list; isHidden() replaces the nine per-widget accessors (hideNoGit, hideNoJj, hideNoRemote, hideZero, hideWhenEmpty, hideIfDisabled, hideStatus/hideTitle, hideWhenNotFork) - Convert existing configs through the standard settings migration (v3 -> v4): legacy boolean flags map to the states each widget type actually hid, so existing configs render identically; default-enabled states are folded into written lists to preserve behavior - Replace per-widget hide toggles with one (h)ide… keybind that opens a shared checklist editor (HideStatesEditor); the items editor injects the keybind for any widget declaring states and shows enabled states as (hide: no-git, zero); 'h' is reserved for this purpose, enforced by a registry-wide test - Add previously missing hide options: zero for token/session-cost/ session-clock widgets and for the git count widgets (changes, insertions, deletions, staged/unstaged/untracked files, conflicts), no-data for speed widgets, Block Timer, and the usage widgets' error placeholders, default-value for Output Style, and a separate no-data state for Git PR - Git Ahead/Behind's hardcoded 0/0 auto-hide becomes a declared default-enabled zero state, so it can now be opted out to show ↑0↓0 - Decorative custom-text/custom-symbol items can opt into merge-target-hidden: the renderer collapses them when the widget they are merged with renders nothing, so icon prefixes no longer orphan - Remove the dead top-level hide field from WidgetItemSchema - Remove shared/git-no-git.ts; slim shared/git-remote.ts and shared/extra-usage-disabled.ts to their remaining responsibilities - Update docs/USAGE.md and tests; add coverage for the hideable module, the v3 -> v4 migration, the renderer merge-target pass, and all newly hideable states Co-authored-by: Claude <noreply@anthropic.com>
fd0f726 to
d78c5c2
Compare
Closes #428 (my proposal from earlier today; happy to rework or split).
Nine per-widget hide keys (
hideNoGit,hideNoJj,hideNoRemote,hideZero,hideWhenEmpty,hideIfDisabled,hideStatus,hideTitle,hideWhenNotFork) become one mechanism: widgets declare conditions via an optionalgetHideableStates(), enabled states live inmetadata.hideas a comma-separated list, and a shared(h)ide…keybind opens a checklist for the selected widget.Diff guide (121 files): ~55 widget files are the same mechanical conversion; most test changes are one-line key swaps.
shared/hideable.ts(new),types/Widget.tsisHidden/get/set (~95 lines)utils/migrations.ts,types/Settings.tshideNoGitalso covered(no upstream)on Ahead/Behind and the no-PR placeholder on Git PR; on-diskgit-pralias handled); one test per mappingHideStatesEditor.tsx(new), items-editor wiringhkeybind opens the checklistutils/renderer.tsmerge-target-hiddenpass: decorative custom-text/symbol items collapse with their merge targetisHidden()USAGE.md,AGENTS.mdBehavior:
zerostate, now opt-out-ablezero(token widgets, session cost/clock, git counters),no-data(speed widgets, Block Timer, Git CI Status'-, usage widgets'[No credentials]-style errors),default-value(Output Style)no-data: they bindhfor the hour toggle; a registry test enforces thehreservationhtoggles become a checklist (Space toggle, Enter save)metadata.hide, so hidden placeholders reappear until upgrading back (in USAGE.md)hide: z.boolean()fromWidgetItemSchema; noupdatemessageadded since rendering is unchangedOpen question: stock Ahead/Behind items now show
(hide: zero)in the editor since defaults are surfaced honestly. Want default-enabled states suppressed from that annotation?Happy to split (core conversion / new states / renderer pass) in whatever order you prefer.
Rebased onto current
main. The conversion covers every widget that landed while this was open, so nothing is left on the old per-widget flags:metricmode now usesisHidden(item, ZERO_HIDEABLE_STATE.key)for per-metric hide-zero, and thehbind it added for metric mode returns to the shared checklist. Compaction Counter keeps onlyvin metric mode.hideWhenEmptybecomes theemptystate, reusingCACHE_EMPTY_HIDEABLE_STATEso it matches the other cache widgets, with acache-timermigration rule.shared/git-no-git, which this PR removes, so it declaresNO_GIT_HIDEABLE_STATEnow.no-datastate its sibling usage widgets declare.emptyconversion, and Extra Usage Used thedisabledstate, from the earlier rebase.wmax-width bind from ✨ feat(widgets): honor maxWidth in Git Branch and Git Root Dir #488 alongside the conversion; Git PR keepss/t.Tested:
bun run lintclean;bun test2064 pass, plus the oneglobal-command-resolutionfailuremainalready has on this host (confirmed against a pristinemaincheckout). Exercised against my real config inside and outside repos.Note: #347 (rules engine) reuses the
hide: z.boolean()field this PR removes and adds rule-based hiding; if that lands first I'll rebase the schema change and align the hide semantics with it.